package org.bigjava.novelplatform.service.impl;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.file.FileReader;
import lombok.extern.slf4j.Slf4j;
import org.bigjava.novelplatform.common.exception.ExceptionCodeMessage;
import org.bigjava.novelplatform.common.exception.UserActionException;
import org.bigjava.novelplatform.common.utils.RedisBuildKey;
import org.bigjava.novelplatform.common.utils.RedisUtils;
import org.bigjava.novelplatform.entity.*;
import org.bigjava.novelplatform.mapper.*;
import org.bigjava.novelplatform.service.AuthorChapterService;
import org.bigjava.novelplatform.service.WriterService;
import org.bigjava.novelplatform.vo.ChapterContent;
import org.bigjava.novelplatform.vo.ReleaseVo;
import org.bigjava.novelplatform.vo.WriterBookVo;
import org.bigjava.novelplatform.vo.WriterInfoVo;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.File;
import java.time.Duration;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static org.bigjava.novelplatform.common.enums.PublishState.PUBLISHED;
import static org.bigjava.novelplatform.common.enums.PublishState.UNPUBLISHED;
import static org.bigjava.novelplatform.common.enums.SaleState.ON_SALE;
import static org.bigjava.novelplatform.common.exception.ExceptionCodeMessage.ILLEGAL_OPERATION;
import static org.bigjava.novelplatform.common.exception.ExceptionCodeMessage.NOT_BOOK;

/**
 * @author ykh
 * @create 2022-05-12 14:51
 */
@Slf4j
@Service
public class WriterServiceImpl implements WriterService {
    @Resource
    private BooksMapper booksMapper;

    @Resource
    private WriterMapper writerMapper;

    @Resource
    private AuthorChapterService authorChapterService;

    @Resource
    private ChapterMapper chapterMapper;

    @Resource
    private CatalogMapper catalogMapper;

    @Resource
    private UsersMapper usersMapper;

    @Resource RedisUtils redisUtils;

    @Override
    public List<Books> getWorksByUserId(Integer userId) {
        List<Books> books = booksMapper.selectByUserId(userId);
        return books;
    }

    @Override
    public ChapterContent saveChapter(ChapterContent chapterContent, Integer id) {
        //查询这本书的信息
        Books books = booksMapper.selectBookById(chapterContent.getBookId());
        Integer writerId = books.getWriterId();
        Writer writer = writerMapper.selectByUserId(id);
        //当前书籍的作者和登录操作用户一致
        if (writer.getId().equals(writerId)) {
            Chapter chapter = new Chapter();
            BeanUtils.copyProperties(chapterContent, chapter);

            //正则匹配
            String regex = "</p>";
            Pattern pattern = Pattern.compile(regex);
            Matcher matcher = pattern.matcher(chapterContent.getContext());
            int count = 0;
            while (matcher.find()) {
                count++;
            }
            chapter.setParagraphCount(count + 1);//设置章节段落数量

            chapter.setWordCount(chapterContent.getContext().length());//设置章节字数
            chapter.setUpdateTime(new Date());//设置章节更新时间
            //新增草稿章节
            if (chapterContent.getId() == null) {
                chapter.setChapterOrder(-1);//设置章节数未发布为 -1
                chapter.setPublish(UNPUBLISHED);//未发布
                //插入章节数据到数据库 并保存文件到磁盘
                authorChapterService.addChapter(chapter, chapterContent.getContext());
            } else {
                //更新草稿章节,并记录历史记录
                authorChapterService.modifiedSection(chapter, chapterContent.getContext(), true);
            }
            ChapterContent content = new ChapterContent();
            BeanUtils.copyProperties(chapter, content);
            return content;
        } else {
            throw new UserActionException(ILLEGAL_OPERATION);
        }

    }

    @Override
    public List<ChapterContent> SelectDraftList(Integer bookId, Integer userId) {
        //book必须是他自己的书
        Writer writer = writerMapper.selectByUserId(userId);
        Books books = booksMapper.selectById(bookId);
        if (books.getWriterId().equals(writer.getId())) {
            List<ChapterContent> list = chapterMapper.selectDraftList(bookId);
            return list;
        } else {
            throw new UserActionException(ILLEGAL_OPERATION);
        }
    }

    @Override
    public String selectChapter(Integer bookId, Long chapterId) {
//        Chapter chapter = chapterMapper.selectById(chapterId);
        Chapter chapter = chapterMapper.selectByIdIncludeDelete(chapterId);
        if (chapterId != null && bookId.equals(chapter.getBookId())) {
            File file = new File(chapter.getChapterUrl());
            String string = FileReader.create(file).readString();
            return string;
        }
        throw new UserActionException(ILLEGAL_OPERATION);
    }

    @Transactional(rollbackFor={RuntimeException.class})
    @Override
    public ChapterContent saveAsDraft(ChapterContent chapterContent, Integer id) {
        //保存章节
        ChapterContent content = saveChapter(chapterContent, id);
        //暂存
        Integer order = authorChapterService.keepChapter(content.getId(), content.getBookId());
        content.setChapterOrder(order);
        return content;
    }

    @Override
    public List<ChapterContent> selectPublishList(Integer bookId, Integer id) {
        Writer writer = writerMapper.selectByUserId(id);
        Books books = booksMapper.selectById(bookId);
        if (books.getWriterId().equals(writer.getId())) {
            List<ChapterContent> list = chapterMapper.selectPublishList(bookId);
            return list;
        } else {
            throw new UserActionException(ILLEGAL_OPERATION);
        }
    }


    @Override
    public List<ChapterContent> selectPublishList(Integer bookId, Integer id, Integer limit) {
        Writer writer = writerMapper.selectByUserId(id);
        Books books = booksMapper.selectById(bookId);
        if (books.getWriterId().equals(writer.getId())) {
            List<ChapterContent> list = chapterMapper.selectPublishListLimit(bookId,limit);
            return list;
        } else {
            throw new UserActionException(ILLEGAL_OPERATION);
        }
    }

    @Override
    public void deleteChapter(Long chapter,Integer userId) {
        //TODO:确认章节是他自己的
        authorChapterService.deleteChapter(chapter);
    }

    @Override
    public void restoreChapter(Long chapterId, Integer id) {
        chapterMapper.restoreChapter(chapterId);
    }

    @Override
    public List<ChapterContent> selectDeleteList(Integer bookId, Integer id) {
        List<ChapterContent> list = chapterMapper.selectDeleteList(bookId);
        return list;
    }

    @Override
    public void releaseBath(ReleaseVo releaseVo) {
        List<Chapter> list = chapterMapper.selectDepositManuscript(releaseVo.getBookId(), releaseVo.getChapterNumber());
        Integer maxOrder =  chapterMapper.maxOrder(releaseVo.getBookId());
        if(maxOrder == null){
            maxOrder = 0;
        }
        Chapter chapter = null;
        int count = 0;
        for (Chapter ch : list) {
            chapter = new Chapter();
            chapter.setId(ch.getId());
            chapter.setChapterOrder(++maxOrder);
            chapter.setPublish(PUBLISHED);
            chapter.setUpdateTime(new Date());
            chapterMapper.updateById(chapter);
            count+=ch.getWordCount();
        }
        if (chapter != null) {
            //TODO:更新书籍的最新章节信息
            Books books = new Books();
            books.setId(releaseVo.getBookId());
            books.setLastChapterId(chapter.getId());
            books.setLastChapterName(chapterMapper.selectChapter(chapter.getId()).getTitle());
            books.setUpdateTime(chapter.getUpdateTime());
            books.setWordCount(count);//增加字数
            books.setChapter(list.size());//增加章节
            booksMapper.updateSimpleById(books);
            //更新作者信息
            writerMapper.updateWordCount(count,books.getId());

        }
        //更新书籍全部章节的redis
        redisUtils.set(null, RedisBuildKey.bindBookChapterInfo(releaseVo.getBookId()), Duration.ofDays(1));
    }

    @Transactional(rollbackFor={RuntimeException.class})
    @Override
    public void release(ReleaseVo releaseVo) {
        Integer bookId = releaseVo.getBookId();
        Integer userId = releaseVo.getUserId();
        Books books = booksMapper.selectById(bookId);
        Writer writer = writerMapper.selectByUserId(userId);
        //确认身份
        if (Objects.equals(writer.getId(), books.getWriterId())) {
            //发布章节
            releaseBath(releaseVo);
        }
    }

    @Override
    public WriterBookVo selectBook(Integer bookId, Integer userId) {
        Writer writer = writerMapper.selectByUserId(userId);

        WriterBookVo books = booksMapper.selectBookByIdUnlimited(bookId);
        if(books.getWriterId().equals(writer.getId())){
            Catalog catalog = catalogMapper.selectParentName(books.getCatalogName());
            Catalog catalog1 = catalogMapper.selectParentName(catalog.getCatalogName());
            books.setStartCatalog(catalog1.getCatalogName());
            books.setCatalogParent(catalog.getCatalogName());
            return books;
        }
        throw new UserActionException(ILLEGAL_OPERATION);

    }

    @Override
    public void updateBook(Books books, Integer id) {
        booksMapper.updateById(books);
    }

    @Override
    public void sale(Integer bookId, Integer id) {
        Books books = new Books();
        books.setSaleState(ON_SALE);
        books.setId(bookId);
        books.setSaleTime(new Date());
        booksMapper.updateById(books);
    }

    @Override
    public void theBookIsOver(Integer bookId, Integer id) {
        Writer writer = writerMapper.selectByUserId(id);
        booksMapper.theBookIsOver(bookId,writer.getId());
    }

    @Override
    public Books selectInSerial(Integer id) {
        Writer writer = writerMapper.selectByUserId(id);
        if (writer.getContinuedBookId() == null) {
            throw new UserActionException(NOT_BOOK);
        }
        Books books = booksMapper.selectById(writer.getContinuedBookId());
        return books;
    }

    @Override
    public WriterInfoVo getWriterInfo(Integer id) {
        Writer writer = writerMapper.selectByUserId(id);
        Users users = usersMapper.selectById(writer.getUserId());
        WriterInfoVo writerInfoVo = new WriterInfoVo();
        writerInfoVo.setBookCount(writer.getBooksCount());
        writerInfoVo.setHeadPortraitUrl(users.getHeadPortraitUrl());
        writerInfoVo.setId(writer.getId());
        writerInfoVo.setNickName(users.getNickName());
        //作者简介：数据库没有这个字段
//        writerInfoVo.setBriefIntroduction();
        Date registerWriterTime = writer.getRegisterWriterTime();
        writerInfoVo.setCreationDays((int) DateUtil.between(registerWriterTime, new Date(), DateUnit.DAY));
        writerInfoVo.setCumulativeNumberOfWords(writer.getWordCount());
        return writerInfoVo;
    }
    /**
     * 获取章节数
     *
     * @param bookId
     * @return
     */
//    @Override
//    public int gianQuery(Integer bookId) {
//        int zhangjieshu = writerMapper.gianQuery(bookId);
//        return zhangjieshu;
//    }
}
